import { Question } from "../interface";

const questions: Question[] = [
    {
        question: "下列代码的输出结果是什么？\nconsole.log(typeof null);",
        radios: [
            "\"object\"",
            "\"null\"",
            "\"undefined\"",
            "Error"
        ],
        desc: "这是JavaScript的历史遗留问题，typeof null 返回 \"object\""
    },
    {
        question: "关于let和var的区别，错误的是：",
        radios: [
            "let有块级作用域，var没有",
            "let存在暂时性死区(TDZ)",
            "var声明的变量会挂载到window对象上",
            "let允许重复声明同名变量"
        ],
        desc: "let不允许重复声明，会抛出SyntaxError"
    },
    {
        question: "下列哪些是JavaScript的基本数据类型？",
        radios: [
            "Symbol",
            "BigInt",
            "Object",
            "Function"
        ],
        muti: true,
        desc: "JS的7种基本类型：undefined/null/boolean/number/string/symbol/bigint"
    },
    {
        question: "关于箭头函数，正确的是：",
        radios: [
            "没有自己的this绑定",
            "可以用作构造函数",
            "有arguments对象",
            "可以使用yield关键字"
        ],
        desc: "箭头函数的this继承自外层作用域，其他选项都是错误描述"
    },
    {
        question: "下列代码的输出结果是什么？\nconsole.log(1 + '2' + 3);",
        radios: [
            "\"123\"",
            "6",
            "\"15\"",
            "\"33\""
        ],
        desc: "+运算符遇到字符串会进行拼接，结果为\"123\""
    },
    {
        question: "关于Promise，错误的是：",
        radios: [
            "Promise.resolve()返回一个fulfilled状态的promise",
            "then()方法返回的是新promise",
            "catch()可以捕获同步错误",
            "finally()不接收任何参数"
        ],
        desc: "catch()只能捕获promise链中的错误，无法捕获同步错误"
    },
    {
        question: "下列哪些方法会改变原数组？",
        radios: [
            "slice()",
            "splice()",
            "sort()",
            "map()"
        ],
        muti: true,
        desc: "splice()和sort()是原地操作，slice()/map()返回新数组"
    },
    {
        question: "关于闭包，正确的是：",
        radios: [
            "会导致内存泄漏",
            "可以访问外部函数变量",
            "会阻止垃圾回收",
            "必须返回函数才能形成闭包"
        ],
        desc: "闭包的本质是函数可以记住并访问其词法作用域"
    },
    {
        question: "下列代码的输出结果是什么？\nconsole.log([] == ![]);",
        radios: [
            "true",
            "false",
            "undefined",
            "Error"
        ],
        desc: "==比较会进行类型转换，最终比较0 == 0"
    },
    {
        question: "关于原型链，错误的是：",
        radios: [
            "Object.prototype是所有对象的原型终点",
            "__proto__是标准属性",
            "Function.prototype是个函数对象",
            "instanceof检查原型链"
        ],
        desc: "__proto__是非标准属性，应使用Object.getPrototypeOf()"
    },
    {
        question: "下列哪些是Map和Object的区别？",
        radios: [
            "Map的键可以是任意类型",
            "Map有size属性",
            "Map保留键值插入顺序",
            "Map可以直接用for...in遍历"
        ],
        muti: true,
        desc: "Map需要用for...of或forEach遍历"
    },
    {
        question: "关于async/await，正确的是：",
        radios: [
            "async函数返回Promise",
            "await可以单独使用",
            "await后面只能跟Promise",
            "async函数内同步错误会被自动catch"
        ],
        desc: "await必须在async函数中使用，可以等待任何值（非Promise会自动包装）"
    },
    {
        question: "下列代码的输出结果是什么？\nsetTimeout(() => console.log(1), 0);\nPromise.resolve().then(() => console.log(2));\nconsole.log(3);",
        radios: [
            "3,2,1",
            "1,2,3",
            "3,1,2",
            "1,3,2"
        ],
        desc: "Promise微任务优先于setTimeout宏任务执行"
    },
    {
        question: "关于this绑定，错误的是：",
        radios: [
            "箭头函数的this由定义位置决定",
            "bind()返回绑定this的新函数",
            "call()和apply()会立即执行函数",
            "new操作符会绑定this到全局对象"
        ],
        desc: "new操作符会将this绑定到新创建的对象"
    },
    {
        question: "下列哪些是ES6模块的特性？",
        radios: [
            "静态加载",
            "支持tree shaking",
            "模块顶层的this指向undefined",
            "import会被提升到模块顶部"
        ],
        muti: true,
        desc: "所有选项都是ES6模块的正确特性"
    },
    {
        question: "关于垃圾回收，正确的是：",
        radios: [
            "标记清除是主要算法",
            "闭包变量不会被回收",
            "WeakMap的键是弱引用",
            "null可以立即释放内存"
        ],
        muti: true,
        desc: "null只是解除引用，内存释放由GC决定"
    },
    {
        question: "下列代码的输出结果是什么？\nfunction foo(a = b, b = 2) {\n  console.log(a, b);\n}\nfoo();",
        radios: [
            "undefined 2",
            "2 2",
            "ReferenceError",
            "undefined undefined"
        ],
        desc: "参数默认值存在暂时性死区，访问未声明的b会报错"
    },
    {
        question: "关于Proxy，错误的是：",
        radios: [
            "可以拦截属性读取",
            "可以拦截in操作符",
            "可以完全替代Object.defineProperty",
            "Proxy.revocable()可创建可撤销代理"
        ],
        desc: "Proxy无法拦截某些底层操作如Object.keys()"
    },
    {
        question: "下列哪些方法属于Function.prototype？",
        radios: [
            "call()",
            "bind()",
            "apply()",
            "toString()"
        ],
        muti: true,
        desc: "所有选项都是Function原型方法"
    },
    {
        question: "关于Generator函数，正确的是：",
        radios: [
            "通过function*声明",
            "yield返回外部传入的值",
            "return()方法终止迭代",
            "throw()方法抛出错误"
        ],
        muti: true,
        desc: "所有选项都是Generator函数的正确特性"
    },
    {
        question: "下列代码的输出结果是什么？\nconst obj = { a: 1 };\nconst obj2 = obj;\nobj2.a = 2;\nconsole.log(obj.a);",
        radios: [
            "1",
            "2",
            "undefined",
            "Error"
        ],
        desc: "对象赋值是引用传递，obj和obj2指向同一内存地址"
    },
    {
        question: "关于Set和WeakSet，错误的是：",
        radios: [
            "Set可以存储任何类型值",
            "WeakSet只能存储对象引用",
            "Set有size属性",
            "WeakSet可以遍历"
        ],
        desc: "WeakSet不可遍历，没有size属性"
    },
    {
        question: "下列哪些场景会创建新的执行上下文？",
        radios: [
            "函数调用",
            "eval执行代码",
            "with语句",
            "块级作用域"
        ],
        muti: true,
        desc: "块级作用域不会创建新的执行上下文（但会创建新的词法环境）"
    },
    {
        question: "关于事件循环，正确的是：",
        radios: [
            "微任务在渲染前执行",
            "setImmediate是浏览器API",
            "process.nextTick是Node.js微任务",
            "宏任务队列优先级高于微任务"
        ],
        muti: true,
        desc: "setImmediate是Node.js特有，浏览器没有"
    },
    {
        question: "下列代码的输出结果是什么？\nconst arr = [1,2];\narr[10] = 10;\nconsole.log(arr.length, arr[5]);",
        radios: [
            "11 undefined",
            "10 10",
            "2 undefined",
            "Error"
        ],
        desc: "直接设置索引10会将length变为11，未赋值的元素为empty（访问返回undefined）"
    },
    {
        question: "关于Object方法，错误的是：",
        radios: [
            "Object.keys()返回可枚举属性",
            "Object.assign()是浅拷贝",
            "Object.freeze()后属性不可修改",
            "Object.create(null)没有原型"
        ],
        desc: "Object.freeze()后仍可修改属性的属性（除非属性本身被冻结）"
    },
    {
        question: "下列哪些操作可能触发隐式类型转换？",
        radios: [
            "==",
            "+",
            "if条件判断",
            "parseInt"
        ],
        muti: true,
        desc: "parseInt是显式转换，其他都可能触发隐式转换"
    },
    {
        question: "关于class语法，正确的是：",
        radios: [
            "extends可以继承内置类型",
            "static方法通过实例调用",
            "私有字段以#开头",
            "super()必须在构造函数第一行调用"
        ],
        muti: true,
        desc: "static方法需要通过类本身调用"
    },
    {
        question: "下列代码的输出结果是什么？\nconsole.log(String.raw`Hello\\nWorld`);",
        radios: [
            "Hello\nWorld",
            "Hello\\nWorld",
            "HelloWorld",
            "Error"
        ],
        desc: "String.raw返回转义前的原始字符串"
    },
    {
        question: "关于正则表达式，错误的是：",
        radios: [
            "/^\\d+$/.test('123')返回true",
            "exec()方法返回匹配数组",
            "g标志表示全局搜索",
            "match()是RegExp对象的方法"
        ],
        desc: "match()是String的方法，exec()才是RegExp的方法"
    },
    {
        question: "下列哪些是Reflect对象的功能？",
        radios: [
            "替代操作符如in/delete",
            "统一的对象操作API",
            "创建可观察对象",
            "替代Function.prototype.apply"
        ],
        muti: true,
        desc: "Reflect不直接提供创建可观察对象的功能"
    }
];

export default questions;
